package test;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.List;

import com.foxinmy.weixin4j.util.URLEncodingUtil;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;

/**
 * server 有粘包问题
 * @author xwalker
 */
public class TimeServer extends Thread{
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			bind(8000);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
    public void bind(int port) throws Exception {
        // 服务器线程组 用于网络事件的处理 一个用于服务器接收客户端的连接
        // 另一个线程组用于处理SocketChannel的网络读写
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            // NIO服务器端的辅助启动类 降低服务器开发难度
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)// 类似NIO中serverSocketChannel
                    .option(ChannelOption.SO_BACKLOG, 1024)// 配置TCP参数
                    .childHandler(new ChildChannelHandler());// 最后绑定I/O事件的处理类
                                                                // 处理网络IO事件

            // 服务器启动后 绑定监听端口 同步等待成功 主要用于异步操作的通知回调 回调处理用的ChildChannelHandler
            ChannelFuture f = serverBootstrap.bind(port).sync();
            System.out.println("timeServer启动");
            // 等待服务端监听端口关闭
            f.channel().closeFuture().sync();

        } finally {
            // 优雅退出 释放线程池资源
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
            System.out.println("服务器优雅的释放了线程资源...");
        }

    }

    /**
     * 网络事件处理器
     */
    private class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast(new StringDecoder(){
            	@Override
            	public boolean acceptInboundMessage(Object msg) throws Exception {
            		// TODO Auto-generated method stub
            		if(super.acceptInboundMessage(msg)){
            			String str = ((ByteBuf)msg).toString(Charset.defaultCharset());
                		System.out.println(str);
                		return "A".equals(str);
            		}else{
            			return false;
            		}
            		
            	}
            	
            	@Override
            	protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
            		// TODO Auto-generated method stub
            		super.decode(ctx, msg, out);
            		System.out.println(out);
            		
            		ctx.write(Unpooled.copiedBuffer("*********************************************\r\n".getBytes()));
//            		ctx.flush();
            	}
            }).addLast(new StringDecoder(){
            	@Override
            	protected void decode(final ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
            		// TODO Auto-generated method stub
            		super.decode(ctx, msg, out);
            		System.err.println(out);
            		final ChannelFuture f = ctx.write(Unpooled.copiedBuffer("-------------------------------------------\r\n".getBytes())).sync().addListener(new ChannelFutureListener() {
						
						@Override
						public void operationComplete(ChannelFuture future) throws Exception {
							// TODO Auto-generated method stub
//							assert f == future;
							ctx.close();
						}
					});
//            		ctx.flush();
            	}
            	@Override
            	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            		// TODO Auto-generated method stub
            		cause.printStackTrace();
            	}
            	
            });
        }

    }

    public static void main(String[] args) throws Exception {
        int port = 8000;
//       TimeServer t = new TimeServer();
//        t.start();
//        Thread.sleep(10000);
//        
//        t.stop();;
        
        System.out.println(URLDecoder.decode( "http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php" ));
        
        System.out.println(URLEncodingUtil.encoding(  "http://192.168.1.4/#/tab/dash", Charset.defaultCharset(), true));
    }

}